def create_file_if_not_exists(filename):
    '''Create a file if it does not exist'''
    try:
        with open(filename, 'x') as f:
            pass
    except FileExistsError:
        pass   
    return None

def check_file_exists(file_path):
    '''Check if a file exists'''
    try:
        with open(file_path, 'r') as f:
            return True 
    except FileNotFoundError:
        return False

def save_to_file(pokemons, filename):
    """Save a collection of dictionaries to a file"""
    try:
        with open(filename, 'w', encoding='utf-8') as file:
            for item in pokemons:
                # 1. Only process dictionary-type data; filter out invalid types
                if not isinstance(item, dict):
                    print(f"Skipping non-dictionary data: {item} (only dictionary type is supported)")
                    continue
                
                # 2. Convert dictionary to custom string: key=value|key=value (handles multi-type values like numbers, lists)
                key_value_pairs = []
                for key, value in item.items():
                    # Special handling for lists (e.g., type=["Electric","Thunder"]), convert to string "Electric,Thunder" for easy subsequent splitting
                    if isinstance(value, list):
                        value_str = ','.join(map(str, value))  # List → comma-separated string
                    else:
                        value_str = str(value)  # Directly convert other types (numbers, strings) to string
                    key_value_pairs.append(f"{key}={value_str}")  # Concatenate into "key=value"
                
                # 3. Combine all key-value pairs, separated by "|" (avoids conflict with commas in values)
                item_str = '|'.join(key_value_pairs)
                # 4. Write to file (one Pokémon per line)
                file.write(item_str + '\n')
        
        print(f"Pokémon data has been saved to the {filename} file.")
    except IOError as e:
        print(f"Error saving file: {e}")
    return None

def load_from_file(filename):
    """Read data from file and restore it to a collection of dictionaries"""
    pokemons = []
    try:
        with open(filename, 'r', encoding='utf-8') as file:
            for line_num, line in enumerate(file, start=1):  # Record line number for easy error location
                # 1. Clean line data: remove leading/trailing whitespace (newlines, spaces), skip empty lines
                line = line.strip()
                if not line:
                    continue
                
                # 2. Split string: split into key-value pairs by "|" (e.g., "id=1", "name=Pikachu")
                key_value_pairs = line.split('|')
                current_pokemon = {}  # Dictionary to store the current Pokémon's data
                
                for pair in key_value_pairs:
                    # Skip key-value pairs with incorrect format (e.g., missing "=")
                    if '=' not in pair:
                        print(f"Format error in line {line_num}, skipping invalid key-value pair: {pair}")
                        continue
                    
                    # 3. Split into key and value: split by the first "=" (avoids issues if "=" exists in the value)
                    key, value_str = pair.split('=', 1)  # split('=',1) only splits at the first occurrence of "="
                    
                    # 4. Restore data type (Key: match the format used when saving)
                    # Case 1: Restore list (saved as comma-separated string; check for commas here)
                    if ',' in value_str:
                        # Further check if it's a pure numeric list (e.g., "1,2,3" → [1,2,3])
                        try:
                            # Attempt to convert to integer list (e.g., level list "25,30" → [25,30])
                            value = list(map(int, value_str.split(',')))
                        except ValueError:
                            # Non-numeric list (e.g., type "Electric,Thunder" → ["Electric","Thunder"])
                            value = value_str.split(',')
                    
                    # Case 2: Restore integer (e.g., "25" → 25; avoid keeping as string)
                    elif value_str.isdigit():
                        value = int(value_str)
                    
                    # Case 3: Restore float (e.g., "3.14" → 3.14; uncomment if needed)
                    # elif value_str.replace('.', '', 1).isdigit() and '.' in value_str:
                    #     value = float(value_str)
                    
                    # Case 4: Other types (strings, e.g., "Pikachu" → "Pikachu")
                    else:
                        value = value_str
                    
                    # 5. Add to the current Pokémon dictionary
                    current_pokemon[key] = value
                
                # 6. If the current Pokémon dictionary is not empty, add it to the result list
                if current_pokemon:
                    pokemons.append(current_pokemon)
        
        print(f"Successfully read {len(pokemons)} Pokémon entries from {filename}.")
    except IOError as e:
        print(f"Error reading file: {e}")
    except Exception as e:
        print(f"Unexpected error parsing file: {e}")
    return pokemons

def count_lines(filename):
    '''Count the number of lines in a file'''
    with open(filename, 'r') as f:
        lines = f.readlines()
    return len(lines)